package com.ukefu.util.sensitive;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.ukefu.core.UKDataContext;
import com.ukefu.webim.service.repository.SensitiveWordRepository;
import com.ukefu.webim.web.model.SensitiveWord;
import com.ukefu.webim.web.model.WorldNode;

/**
 * DF算法判断是否包含敏感词
 * @author iceworld
 *
 */
public class SensitiveFilter {  
	  
    private Map<Integer,WorldNode> sensitiveWorld = new HashMap<Integer,WorldNode>();  
    private static char SIGN = '*';  
    private static SensitiveFilter sensitive = new SensitiveFilter();
    
    public static SensitiveFilter getSensitiveFilter() {
    	return sensitive ;
    }
    
    public void clean() {
    	this.sensitiveWorld.clear(); 
    }
    
    public void initSensitiveWords() {
    	if(sensitiveWorld.size() > 0) {
    		this.clean();
    	}
    	SensitiveWordRepository wordsRes = UKDataContext.getContext().getBean(SensitiveWordRepository.class);
    	this.addSensitiveWorlds(wordsRes.findAll());
    }
      
    public void addSensitiveWorlds(List<SensitiveWord> words) {  
          
        for(SensitiveWord ucword:words) {  
        	StringBuffer strb = new StringBuffer();
        	strb.append(ucword.getKeyword()).append(",").append(ucword.getSuperordinate()).append(",").append(ucword.getContent()) ;
        	String[] sensitiveWords = strb.toString().split(",") ;
        	for(String key : sensitiveWords) {
	            char[] worldCharArray = key.toCharArray();  
	            int convertNum = BCConvert.qj2bj(worldCharArray[0]);  
	            WorldNode senNode = sensitiveWorld.get(convertNum);  
	            //有没有把敏感词首字符放进集合  
	            if(senNode==null) {  
	                senNode = new WorldNode(convertNum, worldCharArray.length==1 , ucword.getOrgi() , ucword.getType());  
	                sensitiveWorld.put(convertNum, senNode);  
	            }else {  
	                //设置字符是否为叶子  
	                if(senNode.isLeaf()) {                    
	                    senNode.setLeaf(worldCharArray.length==1);  
	                }  
	            }  
	            //敏感词子集合  
	            for(int i=1;i<worldCharArray.length;i++) {  
	                boolean flag = i==worldCharArray.length-1;  
	                senNode = senNode.addChildNode(BCConvert.qj2bj(worldCharArray[i]), flag , ucword.getOrgi(), ucword.getType());  
	            }  
        	}
        }  
    }  
      
    public String doFilter(String source , String orgi ,String type) {  
        char[] sourceArray = source.toCharArray();  
        for(int i=0;i<sourceArray.length;i++) {  
            WorldNode findNode = sensitiveWorld.get(BCConvert.qj2bj(sourceArray[i]));  
            if(findNode==null) {  
                continue;  
            }  
            int findFlag = i;  
            boolean senEndMark = false;  
            //单个过滤字符  
            if(findNode.isLeaf()) {  
            	sourceArray[findFlag] = SIGN; 
            }  
            for(;++findFlag<sourceArray.length;) {  
                findNode = findNode.queryChildNode(BCConvert.qj2bj(sourceArray[findFlag]));  
                if(findNode==null) {  
                    break;  
                }  
                if(findNode.isLeaf() && findNode.getOrgi().equals(orgi) && findNode.getType().equals(type)) {  
                    senEndMark = true;  
                    break;  
                }  
            }  
            if(senEndMark) {  
                for(int k=i;k<=findFlag;k++) {  
                    sourceArray[k] = SIGN;  
                }  
                i=findFlag;  
            }  
        }  
        return new String(sourceArray);  
    }  
    
    public boolean hasSensitiveWords(String source ,String orgi ,String type) {  
        char[] sourceArray = source.toCharArray();  
        boolean hasSensitive = false ;
        for(int i=0;i<sourceArray.length;i++) {  
            WorldNode findNode = sensitiveWorld.get(BCConvert.qj2bj(sourceArray[i]));  
            if(findNode==null) {  
                continue;  
            }  
            int findFlag = i;  
            boolean senEndMark = false;  
            //单个过滤字符  
            if(findNode.isLeaf()) {  
            	return true;  
            }  
            for(;++findFlag<sourceArray.length;) {  
                findNode = findNode.queryChildNode(BCConvert.qj2bj(sourceArray[findFlag]));
                if(findNode==null) {  
                    break;  
                }
                if(findNode.isLeaf() && findNode.getOrgi().equals(orgi) && findNode.getType().equals(type)) {  
                    senEndMark = true;  
                    hasSensitive = true ;
                    break;  
                }
            }  
            if(senEndMark) {  
                for(int k=i;k<=findFlag;k++) {  
                    sourceArray[k] = SIGN;  
                }  
                i=findFlag;  
            }  
        }  
        return hasSensitive;  
    }  
      
    public static void main(String[] args) {  
        List<SensitiveWord> list = new ArrayList<SensitiveWord>();  
        SensitiveWord words = new SensitiveWord("星空" , "天空" , "星星" ) ; 
        words.setOrgi("ukewo");
        words.setType("agent");
        list.add(words);  
        SensitiveWord  words2 = new SensitiveWord("马路" , "行走" , "哈哈" ) ; 
        words2.setOrgi("ukewo");
        words2.setType("agent");
        list.add(words2);  
        SensitiveFilter filter = new SensitiveFilter();
        filter.addSensitiveWorlds(list);  
          
        String doFilterStr = filter.doFilter("在漫天星空下载马路上行走，哈哈" , "ukewo" , "agent");  
        System.out.println(doFilterStr);
        
        System.out.println(filter.hasSensitiveWords("在漫天星空下载马路上行走，哈哈", "ukewo" , "agent"));
          
    }  
}  